<template>
  <div class="env-config-container">
    <el-card>
      <template #header>
        <div class="card-header">
          <span>环境变量配置</span>
          <div>
            <el-button @click="handleRefreshCache" :loading="refreshing">刷新配置缓存</el-button>
            <el-button type="primary" @click="handleSave" :loading="saving">保存配置</el-button>
            <el-button type="success" @click="handleAdd">添加配置</el-button>
          </div>
        </div>
      </template>

      <el-alert
        title="提示"
        type="warning"
        :closable="false"
        show-icon
        style="margin-bottom: 20px"
      >
        <template #default>
          <p>修改环境变量后，请点击"保存配置"按钮保存更改，然后点击"刷新配置缓存"使配置生效。</p>
          <p><strong>注意：</strong>修改关键配置（如数据库密码、JWT密钥等）可能会影响系统运行，请谨慎操作。</p>
        </template>
      </el-alert>

      <!-- 搜索和过滤 -->
      <el-row :gutter="20" style="margin-bottom: 20px">
        <el-col :span="8">
          <el-input
            v-model="searchText"
            placeholder="搜索配置项..."
            clearable
            @input="handleSearch"
          >
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
          </el-input>
        </el-col>
        <el-col :span="8">
          <el-select
            v-model="selectedGroup"
            placeholder="选择配置分组"
            clearable
            @change="handleGroupFilter"
          >
            <el-option label="全部" value="" />
            <el-option
              v-for="(group, key) in configGroups"
              :key="key"
              :label="group.title"
              :value="key"
            />
          </el-select>
        </el-col>
        <el-col :span="8">
          <el-button @click="handleLoad">重新加载</el-button>
          <el-button @click="handleRefreshCache" :loading="refreshing">刷新缓存</el-button>
        </el-col>
      </el-row>

      <!-- 配置分组 -->
      <el-collapse v-model="activeGroups">
        <el-collapse-item
          v-for="(group, groupKey) in filteredGroups"
          :key="groupKey"
          :name="groupKey"
        >
          <template #title>
            <span style="font-weight: 500; font-size: 16px">{{ group.title }}</span>
            <el-tag type="info" size="small" style="margin-left: 10px">{{ group.items.length }} 项</el-tag>
          </template>
          <el-table :data="group.items" border style="width: 100%">
            <el-table-column prop="key" label="配置键" width="280">
              <template #default="{ row }">
                <el-tag type="info" effect="plain">{{ row.key }}</el-tag>
              </template>
            </el-table-column>
            <el-table-column prop="value" label="配置值" min-width="400">
              <template #default="{ row }">
                <el-input
                  v-if="!isProtectedKey(row.key)"
                  v-model="row.value"
                  :type="isPasswordKey(row.key) ? 'password' : 'text'"
                  :show-password="isPasswordKey(row.key) && row.value"
                  placeholder="请输入配置值"
                />
                <div v-else class="protected-value">
                  <el-icon><Lock /></el-icon>
                  <span>受保护配置，无法编辑</span>
                </div>
              </template>
            </el-table-column>
            <el-table-column label="操作" width="120" align="center" fixed="right">
              <template #default="{ row }">
                <el-button
                  v-if="!isProtectedKey(row.key)"
                  type="danger"
                  link
                  size="small"
                  @click="handleDelete(row)"
                >
                  删除
                </el-button>
                <el-tag v-else type="warning" size="small">受保护</el-tag>
              </template>
            </el-table-column>
          </el-table>
        </el-collapse-item>
      </el-collapse>

      <!-- 空状态 -->
      <el-empty v-if="!hasConfig" description="暂无配置数据" />
    </el-card>

    <!-- 添加配置对话框 -->
    <el-dialog v-model="addDialogVisible" title="添加配置" width="600px">
      <el-form ref="addFormRef" :model="addForm" :rules="addRules" label-width="120px">
        <el-form-item label="配置键" prop="key">
          <el-input v-model="addForm.key" placeholder="例如：NEW_CONFIG_KEY" />
          <div class="form-tip">配置键必须为大写字母、数字和下划线组成</div>
        </el-form-item>
        <el-form-item label="配置值" prop="value">
          <el-input
            v-model="addForm.value"
            type="textarea"
            :rows="3"
            placeholder="请输入配置值"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="addDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="handleConfirmAdd" :loading="saving">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Lock } from '@element-plus/icons-vue'
import request from '@/utils/request'

const saving = ref(false)
const refreshing = ref(false)
const addDialogVisible = ref(false)
const searchText = ref('')
const selectedGroup = ref('')
const activeGroups = ref([])

const configGroups = ref({})
const originalConfigGroups = ref({})

const addFormRef = ref(null)
const addForm = reactive({
  key: '',
  value: '',
})

const addRules = {
  key: [
    { required: true, message: '请输入配置键', trigger: 'blur' },
    {
      pattern: /^[A-Z_][A-Z0-9_]*$/,
      message: '配置键必须为大写字母、数字和下划线组成，且以字母或下划线开头',
      trigger: 'blur',
    },
  ],
  value: [
    { required: false, message: '配置值可以为空', trigger: 'blur' },
  ],
}

// 受保护的配置键（不能编辑和删除）
const protectedKeys = ['APP_KEY', 'JWT_SECRET', 'DB_PASSWORD']

// 密码类型的配置键（显示为密码输入框）
const passwordKeys = [
  'DB_PASSWORD',
  'REDIS_PASSWORD',
  'JWT_SECRET',
  'APP_KEY',
  'MAIL_PASSWORD',
]

// 计算属性：过滤后的分组
const filteredGroups = computed(() => {
  let groups = { ...configGroups.value }

  // 按分组过滤
  if (selectedGroup.value) {
    const filtered = {}
    if (groups[selectedGroup.value]) {
      filtered[selectedGroup.value] = groups[selectedGroup.value]
    }
    groups = filtered
  }

  // 按搜索文本过滤
  if (searchText.value) {
    const search = searchText.value.toLowerCase()
    const filtered = {}
    for (const [groupKey, group] of Object.entries(groups)) {
      const filteredItems = group.items.filter(
        (item) =>
          item.key.toLowerCase().includes(search) ||
          item.value.toLowerCase().includes(search)
      )
      if (filteredItems.length > 0) {
        filtered[groupKey] = {
          ...group,
          items: filteredItems,
        }
      }
    }
    groups = filtered
  }

  return groups
})

// 计算属性：是否有配置
const hasConfig = computed(() => {
  return Object.keys(filteredGroups.value).length > 0
})

// 判断是否为受保护的配置键
const isProtectedKey = (key) => {
  return protectedKeys.includes(key)
}

// 判断是否为密码类型的配置键
const isPasswordKey = (key) => {
  return passwordKeys.includes(key)
}

// 加载配置
const loadConfig = async () => {
  try {
    const res = await request.get('/env-config')
    if (res.code === 200 && res.data) {
      configGroups.value = res.data
      originalConfigGroups.value = JSON.parse(JSON.stringify(res.data))
      // 默认展开所有分组
      activeGroups.value = Object.keys(res.data)
    }
  } catch (error) {
    console.error('加载配置失败:', error)
    ElMessage.error('加载配置失败')
  }
}

// 配置变更处理
const handleConfigChange = (row) => {
  // 实时保存可以在输入框失焦时触发，这里只是标记
  // 实际保存需要点击"保存配置"按钮
}

// 保存配置
const handleSave = async () => {
  try {
    // 收集所有配置（包括修改和未修改的）
    const configs = []
    let hasChanges = false
    
    // 构建原始配置的映射
    const originalConfigMap = {}
    for (const group of Object.values(originalConfigGroups.value)) {
      for (const item of group.items) {
        originalConfigMap[item.key] = item.value || ''
      }
    }
    
    // 收集当前所有配置，并检测变更
    for (const group of Object.values(configGroups.value)) {
      for (const item of group.items) {
        // 跳过受保护的配置
        if (!isProtectedKey(item.key)) {
          const originalValue = originalConfigMap[item.key] || ''
          const currentValue = item.value || ''
          
          // 检查是否有变更
          if (originalValue !== currentValue) {
            hasChanges = true
          }
          
          configs.push({
            key: item.key,
            value: currentValue,
          })
        }
      }
    }

    if (configs.length === 0) {
      ElMessage.warning('没有需要保存的配置')
      return
    }
    
    if (!hasChanges) {
      ElMessage.info('配置没有变更，无需保存')
      return
    }

    saving.value = true

    const res = await request.put('/env-config', { configs })

    if (res.code === 200) {
      ElMessage.success('配置保存成功，配置缓存已清除')
      // 重新加载配置，更新原始配置
      await loadConfig()
    } else {
      ElMessage.error(res.message || '保存失败')
    }
  } catch (error) {
    if (error.errors) {
      ElMessage.error('验证失败，请检查输入')
    } else {
      ElMessage.error(error.message || '保存失败')
    }
  } finally {
    saving.value = false
  }
}

// 删除配置
const handleDelete = async (row) => {
  try {
    await ElMessageBox.confirm(
      `确定要删除配置项 "${row.key}" 吗？`,
      '提示',
      {
        type: 'warning',
      }
    )

    // 使用 POST 请求删除，因为某些浏览器/服务器不支持 DELETE 请求体
    const res = await request.post('/env-config/delete', {
      keys: [row.key],
    })

    if (res.code === 200) {
      ElMessage.success('配置删除成功，配置缓存已清除')
      // 重新加载配置
      await loadConfig()
    } else {
      ElMessage.error(res.message || '删除失败')
    }
  } catch (error) {
    if (error.message === 'cancel' || error === 'cancel') {
      // 用户取消
      return
    }
    ElMessage.error(error.message || '删除失败')
  }
}

// 添加配置
const handleAdd = () => {
  addForm.key = ''
  addForm.value = ''
  addDialogVisible.value = true
}

// 确认添加
const handleConfirmAdd = async () => {
  try {
    await addFormRef.value.validate()

    // 检查键是否已存在
    for (const group of Object.values(configGroups.value)) {
      if (group.items.some((item) => item.key === addForm.key)) {
        ElMessage.error('配置键已存在')
        return
      }
    }

    saving.value = true

    const res = await request.post('/env-config', {
      key: addForm.key,
      value: addForm.value || '',
    })

    if (res.code === 200) {
      ElMessage.success('配置添加成功，配置缓存已清除')
      addDialogVisible.value = false
      // 重新加载配置
      await loadConfig()
    } else {
      ElMessage.error(res.message || '添加失败')
    }
  } catch (error) {
    if (error.errors) {
      ElMessage.error('验证失败，请检查输入')
    } else {
      ElMessage.error(error.message || '添加失败')
    }
  } finally {
    saving.value = false
  }
}

// 刷新配置缓存
const handleRefreshCache = async () => {
  try {
    refreshing.value = true

    const res = await request.post('/env-config/refresh')

    if (res.code === 200) {
      ElMessage.success('配置缓存已刷新，新配置已生效')
      // 重新加载配置
      await loadConfig()
    } else {
      ElMessage.error(res.message || '刷新配置缓存失败')
    }
  } catch (error) {
    ElMessage.error(error.message || '刷新配置缓存失败')
  } finally {
    refreshing.value = false
  }
}

// 重新加载
const handleLoad = async () => {
  await loadConfig()
  ElMessage.success('配置已重新加载')
}

// 搜索处理
const handleSearch = () => {
  // 搜索逻辑已在 computed 中处理
}

// 分组过滤处理
const handleGroupFilter = () => {
  // 过滤逻辑已在 computed 中处理
}

onMounted(() => {
  loadConfig()
})
</script>

<style scoped lang="scss">
.env-config-container {
  // padding 由 app-container 统一管理
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.form-tip {
  font-size: 12px;
  color: #909399;
  margin-top: 5px;
  line-height: 1.6;
}

:deep(.el-collapse-item__header) {
  font-size: 16px;
  font-weight: 500;
}

:deep(.el-table) {
  .el-table__cell {
    padding: 12px 0;
  }
}

.protected-value {
  display: flex;
  align-items: center;
  gap: 8px;
  color: #909399;
  font-size: 14px;
}
</style>

